package com.kool.kmqtt.server.repository;

import com.kool.kmqtt.server.log.ClientNoAckSendPacketCnt;
import com.kool.kmqtt.server.packet.Packet;
import com.kool.kmqtt.server.repository.subscription.SubscribeInfo;
import com.kool.kmqtt.server.repository.subscription.Subscriber;
import com.kool.kmqtt.server.repository.subscription.Subscription;
import com.kool.kmqtt.server.session.WillStatus;

import java.util.List;

public interface Repository {
    /**
     * 删除客户端的会话状态
     * 会话状态包括：订阅信息、遗嘱信息、出站未确认PUBLISH、PUBREL报文
     *
     * @param clientId
     */
    void deleteSessionStatus(String clientId);

    /**
     * 保存客户端遗嘱信息
     *
     * @param clientId
     * @param willStatus
     */
    void saveWillStatus(String clientId, WillStatus willStatus);

    /**
     * 删除客户端的遗嘱信息
     *
     * @param clientId
     */
    void deleteWillStatus(String clientId);

    /**
     * 查询客户端的遗嘱信息
     *
     * @param clientId
     * @return
     */
    WillStatus getWillStatus(String clientId);

    /**
     * 查询所有订阅信息
     *
     * @return
     */
    List<Subscription> getSubscriptions();

    /**
     * 保存客户端的主题过滤器列表
     *
     * @param clientId
     * @param subscribeInfo
     */
    void saveSubscribeInfo(String clientId, SubscribeInfo subscribeInfo);

    /**
     * 获取与主题匹配的主题过滤器对应的客户端信息
     *
     * @param topic
     * @return
     */
    List<Subscriber> getSubscriber(String topic);

    /**
     * 删除客户端的一个订阅主题过滤器
     *
     * @param clientId
     * @param topicFilter
     */
    void deleteSubscribeInfo(String clientId, String topicFilter);

    /**
     * 删除客户端的所有订阅信息
     *
     * @param clientId
     */
    void deleteSubscriber(String clientId);

    /**
     * 保存未确认的入站PUBLISH QoS1 QoS2报文和PUBREL报文
     *
     * @param clientId
     * @param packet
     */
    void saveReceivePacket(String clientId, Packet packet);

    /**
     * 获取未确认的入站PUBLISH QoS1 QoS2报文或PUBREL报文
     *
     * @param packetId
     * @return
     */
    Packet getReceivePacket(int packetId);

    /**
     * 删除未确认的入站PUBLISH QoS1 QoS2报文或PUBREL报文
     *
     * @param packetId
     */
    void deleteReceivePacket(int packetId);

    /**
     * 保存保留消息
     *
     * @param topicName
     * @param packet
     */
    void saveRetainPacket(String topicName, Packet packet);

    /**
     * 获取主题过滤器匹配的保留消息
     *
     * @param topicFilter
     * @return
     */
    List<Packet> getRetainPacket(String topicFilter);

    /**
     * 清空主题下的保留消息
     *
     * @param topicName
     */
    void deleteRetainPackets(String topicName);

    /**
     * 保存未确认的出站PUBLISH或PUBREL报文
     *
     * @param clientId
     * @param packet
     */
    void saveSendPackets(String clientId, Packet packet);

    /**
     * 删除客户端的所有出站未确认的出站PUBLISH或PUBREL报文
     *
     * @param clientId
     */
    void deleteSendPackets(String clientId);

    /**
     * 查询出站未确认的出站PUBLISH或PUBREL报文
     *
     * @param clientId
     * @return
     */
    List<Packet> getSendPackets(String clientId);

    /**
     * 删除1条出站未确认的出站PUBLISH或PUBREL报文
     *
     * @param clientId
     * @param packetId
     */
    void deleteSendPacket(String clientId, int packetId);

    /**
     * 统计所有客户端出站未确认消息数
     *
     * @return
     */
    List<ClientNoAckSendPacketCnt> countSendPacket();

    /**
     * 查询客户端的连接错误次数
     *
     * @param remoteAddress
     * @return
     */
    Integer getClientConnectErrorTimes(String remoteAddress);

    /**
     * 客户端连接次数自增1，超时过期，单位：秒
     *
     * @param remoteAddress
     * @param timeoutSeconds
     */
    void increaseFailoverCounter(String remoteAddress, int timeoutSeconds);
}
